/**
 * 编写一个像sum(a)(b) = a + b 这样工作的sum函数。
 */
// 为了使第二个括号有效，第一个括号必须返回一个函数。
function sum(a) {
    return function(b) {
        return a + b // 从外部词法环境获得“a” (闭包)
    }
}
alert(sum(1)(2)) // 3

// 因此，可以引出：函数柯里化。

/**
 * 其他：
 *  在js中，所有函数都是天生闭包的（只有一个例外“new Function”语法）
 * 使用new Function 创建的函数，它的环境指向 [全局词法环境] ，而不是函数所在的外部词法环境。
 * 因此，我们不能在 new Function 中直接使用外部变量。
 */

/**
 * ## 模块模式 ## 
 * 需要具备两个必要条件：
 *  1. 必须有外部的封闭函数（该函数必须至少被调用一次，每次调用都会创建一个新的模块实例。）
 *  2. 封闭函数必须返回至少一个内部函数，这样内部函数才能在私有作用域中形成闭包，并且可以访问或者修改私有的状态。
 */
// 一个具有函数属性的对象本身并不是真正的模块。从方便观察的角度看，一个从函数调用所返回的，只有数据属性而没有闭包函数的对象并不是真正的模块。